<template>
  <Mapbox :mapOnLoadCB="mapOnLoadCB"></Mapbox>
  <div class='overlay'>
    <button id='replay'>Replay</button>
  </div>
</template>

<script>
import {ref} from "vue"
import Mapbox from "@/components/common/Mapbox.component.vue"
import MapboxCommonService from "@/service/map/MapboxCommonService"

export default {
  name: "SymbolFly.component",
  components: {Mapbox},
  setup() {

    let origin = [-122.414, 37.776]
    // A simple line from origin to destination.
    let route = {
      "type": "FeatureCollection",
      "features": [{
        "type": "Feature",
        "geometry": {
          "type": "LineString",
          "coordinates": [origin, [-77.032, 38.913]]
        }
      }]
    };

    // A single point that animates along the route.
    // Coordinates are initially set to origin.
    let point = {
      "type": "FeatureCollection",
      "features": [{
        "type": "Feature",
        "properties": {},
        "geometry": {
          "type": "Point",
          "coordinates": origin
        }
      }]
    };

    // Calculate the distance in kilometers between route start/end point.
    let lineDistance = turf.lineDistance(route.features[0], 'kilometers');

    let arc = [];

    // Number of steps to use in the arc and animation, more steps means
    // a smoother arc and animation, but too many steps will result in a
    // low frame rate
    let steps = 500;

    // Draw an arc between the `origin` & `destination` of the two points
    for (let i = 0; i < lineDistance; i += lineDistance / steps) {
      let segment = turf.along(route.features[0], i, 'kilometers');
      arc.push(segment.geometry.coordinates);
    }

    // Update the route with calculated arc coordinates
    route.features[0].geometry.coordinates = arc;

    // Used to increment the value of the point measurement against the route.
    let counter = 0;

    let mapStore = ref({});
    let mapOnLoadCB = (map) => {
      mapStore.value = map;
      MapboxCommonService.setCZBP(map, [-96, 37.8], 3)

      // 使用 Turf 平滑地沿指定路线为点设置动画效果。
      // Add a source and layer displaying a point which will be animated in a circle.
      map.addSource('route', {
        "type": "geojson",
        "data": route
      });

      map.addSource('point', {
        "type": "geojson",
        "data": point
      });

      map.addLayer({
        "id": "route",
        "source": "route",
        "type": "line",
        "paint": {
          "line-width": 2,
          "line-color": "#007cbf"
        }
      });

      map.addLayer({
        "id": "point",
        "source": "point",
        "type": "symbol",
        "layout": {
          "icon-image": "airport-15",
          "icon-rotate": ["get", "bearing"],
          "icon-rotation-alignment": "map",
          "icon-allow-overlap": true,
          "icon-ignore-placement": true
        }
      });

      const animate = () => {
        // Update point geometry to a new position based on counter denoting
        // the index to access the arc.
        point.features[0].geometry.coordinates = route.features[0].geometry.coordinates[counter];

        // Calculate the bearing to ensure the icon is rotated to match the route arc
        // The bearing is calculate between the current point and the next point, except
        // at the end of the arc use the previous point and the current point
        point.features[0].properties.bearing = turf.bearing(
            turf.point(route.features[0].geometry.coordinates[counter >= steps ? counter - 1 : counter]),
            turf.point(route.features[0].geometry.coordinates[counter >= steps ? counter : counter + 1])
        );

        // Update the source with this new data.
        map.getSource('point').setData(point);

        // Request the next frame of animation so long the end has not been reached.
        if (counter < steps) {
          requestAnimationFrame(animate);
        }

        counter = counter + 1;
      }

      document.getElementById('replay').addEventListener('click', function () {
        // Set the coordinates of the original point back to origin
        point.features[0].geometry.coordinates = origin;

        // Update the source layer
        map.getSource('point').setData(point);

        // Reset the counter
        counter = 0;

        // Restart the animation.
        animate(counter);
      });

      // Start the animation.
      // animate(counter);
    };

    return {
      mapOnLoadCB
    }
  }
}
</script>

<style scoped lang="scss">
.overlay {
  position: absolute;
  top: 10px;
  left: 10px;
}

.overlay button {
  font: 600 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
  background-color: #3386c0;
  color: #fff;
  display: inline-block;
  margin: 0;
  padding: 10px 20px;
  border: none;
  cursor: pointer;
  border-radius: 3px;
}

.overlay button:hover {
  background-color: #4ea0da;
}
</style>